home *** CD-ROM | disk | FTP | other *** search
/ Shareware Grab Bag / Shareware Grab Bag.iso / 007 / xinu.arc / XINUC2.C < prev    next >
Text File  |  1986-01-03  |  11KB  |  463 lines

  1. /* mark.c - _mkinit, mark  p. 232 */
  2.  
  3. # include    <conf.h>
  4. # include    <kernel.h>
  5. # include    <mark.h>
  6.  
  7. # ifdef    MEMMARK
  8. int    *marks[MAXMARK];
  9. int    nmarks;
  10. int    mkmutex;
  11.  
  12. /*-----------------------------------------------------------------------------
  13.  *  _mkinit  --  called once at system startup
  14.  *-----------------------------------------------------------------------------
  15.  */
  16. _mkinit()
  17. {
  18.     mkmutex = screate(1);
  19.     nmarks = 0;
  20. }
  21.  
  22. /*-----------------------------------------------------------------------------
  23.  *  mark  --  mark a location if it hasn't been marked
  24.  *-----------------------------------------------------------------------------
  25.  */
  26. mark(loc)
  27.     int    *loc;
  28. {
  29.     if (*loc>=0 && *loc<nmarks && marks[*loc]==loc)
  30.         return(0);
  31.     if (nmarks>=MAXMARK)
  32.         return(SYSERR);
  33.     wait(mkmutex);
  34.     marks[(*loc) = nmarks++] = loc;
  35.     signal(mkmutex);
  36.     return(OK);
  37. }
  38. # endif
  39. /*  memread.c  */
  40.  
  41. # include    <conf.h>
  42. # include    <kernel.h>
  43. # include    <proc.h>
  44. # include    <disk.h>
  45.  
  46. /*-----------------------------------------------------------------------------
  47.  *  memread  --  read a block from the 'memory' device
  48.  *-----------------------------------------------------------------------------
  49.  */
  50. memread(devptr, buff, block)
  51.     struct devsw    *devptr;
  52.     char    *buff;
  53.     DBADDR    block;
  54. {
  55.         char *addr;
  56.     int cnt;
  57.  
  58.     /* convert block number into byte address by multiplying 'block'
  59.        by DBUFSIZ. Be careful with this computation, since the
  60.        effect of multiplying block by DBUFSIZ with result in a
  61.        long. So we first convert block to a long to allow the
  62.        multiplication to work. If you did the multiplication first,
  63.        then the casting you would get an integer extended to a long.
  64.        This just doesn't work. There also isn't any checking for
  65.        out of range. */
  66.  
  67.     addr = (char *)((long)block * DBUFSIZ);
  68.  
  69.     /* copy the data to the user's buffer area */
  70. è    for( cnt = DBUFSIZ; cnt--; ) *buff++ = *addr++;
  71.  
  72.     return(OK);
  73. }
  74. /*  memwrite.c  */
  75.  
  76. # include    <conf.h>
  77. # include    <kernel.h>
  78. # include    <proc.h>
  79. # include    <disk.h>
  80.  
  81. /*-----------------------------------------------------------------------------
  82.  *  memwrite  --  write a block to the 'memory' device
  83.  *-----------------------------------------------------------------------------
  84.  */
  85. memwrite(devptr, buff, block)
  86.     struct devsw    *devptr;
  87.     char    *buff;
  88.     DBADDR    block;
  89. {
  90.         char *addr;
  91.     int cnt;
  92.  
  93.     /* see comment in memread. */
  94.     addr = (char *)((long)block * DBUFSIZ);
  95.  
  96.     /* copy the data from the user's buffer area */
  97.  
  98.     for( cnt = DBUFSIZ; cnt--; ) *addr++ = *cnt++;
  99.  
  100.     return(OK);
  101. }
  102. /* mkpool.c - mkpool  p. 238 */
  103.  
  104. # include    <conf.h>
  105. # include    <kernel.h>
  106. # include    <mark.h>
  107. # include    <bufpool.h>
  108.  
  109. /*-----------------------------------------------------------------------------
  110.  *  mkpool  --  allocate memory for a buffer pool and link together
  111.  *-----------------------------------------------------------------------------
  112.  */
  113. mkpool(bufsiz, numbufs)
  114.     int    bufsiz, numbufs;
  115. {
  116.     char    ps;
  117.     int    poolid;
  118.     char    *where;
  119.  
  120. # ifdef    MEMMARK
  121.     if (unmarked(bpmark))
  122.         poolinit();
  123. # endif
  124.     disable(ps);
  125.     if (bufsiz<BPMINB || bufsiz>BPMAXB
  126.         || numbufs<1 || numbufs>BPMAXN
  127.         || nbpools>=NBPOOLS
  128.         || (where=getmem((bufsiz+sizeof(int))*numbufs)) == SYSERR)  {
  129.         restore(ps);
  130.         return(SYSERR);
  131.     }
  132.     poolid = nbpools++;
  133.     bptab[poolid].bpnext = where;
  134.     bptab[poolid].bpsize = bufsiz;
  135.     bptab[poolid].bpsem = screate(numbufs);
  136.     bufsiz += sizeof(int);
  137.     for (numbufs-- ; numbufs>0 ; numbufs--, where+=bufsiz)
  138.         *((int *)where) = (int)(where + bufsiz);
  139.     *((int *)where) = (int)NULL;
  140.     restore(ps);
  141.     return(poolid);
  142. }
  143. /* newqueue.c - newqueue  p. 50 */
  144.  
  145. # include    <conf.h>
  146. # include    <kernel.h>
  147. # include    <q.h>
  148.  
  149. /*-----------------------------------------------------------------------------
  150.  * newqueue  --  initialize a new list in the q structure
  151.  *-----------------------------------------------------------------------------
  152.  */
  153. int    newqueue()
  154. {
  155.     struct qent    *hptr;        /* address of new list head          */
  156.     struct qent    *tptr;        /* address of new list tail          */
  157.     int    hindex, tindex;        /* head and tail indexes             */
  158.  
  159.     hptr = &q[hindex=nextqueue++];    /* nextqueue is global variable      */
  160.     tptr = &q[tindex=nextqueue++];    /* giving next used q pos.           */
  161.     hptr->qnext = tindex;
  162.     hptr->qprev = EMPTY;
  163.     hptr->qkey  = MININT;
  164.     tptr->qnext = EMPTY;
  165.     tptr->qprev = hindex;
  166.     tptr->qkey  = MAXINT;
  167.     return(hindex);
  168. }
  169. /* open.c - open  p. 150 */
  170.  
  171. # include    <conf.h>
  172. # include    <kernel.h>
  173. # include    <io.h>
  174.  
  175. /*-----------------------------------------------------------------------------
  176.  *  open  --  open a connection to a device/file (params 2&3 are optional)
  177.  *-----------------------------------------------------------------------------
  178.  */
  179. open(descrp, nam, mode)
  180.     int    descrp;
  181.     char    *nam, *mode;
  182. {
  183.     struct devsw    *devptr;
  184.  
  185.     if (isbaddev(descrp))
  186.         return(SYSERR);
  187.     devptr = &devtab[descrp];
  188.     return ((*devptr->dvopen)(devptr,nam,mode));
  189. }
  190. /* pcreate.c - pcreate  p. 244 */
  191.  
  192. # include    <conf.h>
  193. # include    <kernel.h>
  194. # include    <mark.h>
  195. # include    <ports.h>
  196.  
  197. /*-----------------------------------------------------------------------------
  198.  *  pcreate  --  create a port thet allows "count" outstanding messages
  199.  *-----------------------------------------------------------------------------
  200.  */
  201. SYSCALL    pcreate(count)
  202.     int    count;
  203. {
  204.     char    ps;
  205.     int    i, p;
  206.     struct pt    *ptptr;
  207.  
  208.     if (count < 0)
  209.         return(SYSERR);
  210.     disable(ps);
  211. # ifdef    MEMMARK
  212.     if (mark(ptmark) == OK)
  213.         pinit(MAXMSGS);
  214. # endif
  215.     for (i=0 ; i<NPORTS ; i++)  {
  216.         if ((p=ptnextp--) <= 0)
  217.             ptnextp - NPORTS - 1;
  218.         if ((ptptr=&ports[p])->ptstate == PTFREE)  {
  219.             ptptr->ptstate = PTALLOC;
  220.             ptptr->ptssem  = screate(count);
  221.             ptptr->ptrsem  = screate(0);
  222.             ptptr->pthead  = ptptr->pttail = NULL;
  223.             ptptr->ptseq++;
  224.             ptptr->ptmaxcnt = count;
  225.             restore(ps);
  226.             return(p);
  227.         }
  228.     }
  229.     restore(ps);
  230.     return(SYSERR);
  231. }
  232. /* pdelete.c - pdelete  p. 250 */
  233.  
  234. # include    <conf.h>
  235. # include    <kernel.h>
  236. # include    <mark.h>
  237. # include    <ports.h>
  238.  
  239. /*-----------------------------------------------------------------------------
  240.  *  pdelete  --  delete a port, freeing waiting processes and messages
  241.  *-----------------------------------------------------------------------------
  242.  */
  243. SYSCALL    pdelete(portid, dispose)
  244.     int    portid;
  245.     int    (*dispose)();
  246. {
  247.     char    ps;
  248.     struct pt    *ptptr;
  249.  
  250.     disable(ps);
  251.     if (isbadport(portid) ||
  252. # ifdef    MEMMARK
  253.       unmarked(ptmark) ||
  254. # endif
  255.       (ptptr=&ports[portid])->ptstate != PTALLOC)  {
  256.         restore(ps);
  257.         return(SYSERR);
  258.     }
  259.     _ptclear(ptptr, PTFREE, dispose);
  260.     restore(ps);
  261.     return(OK);
  262. }
  263. /* pinit.c - pinit  p. 243 */
  264.  
  265. # include    <conf.h>
  266. # include    <kernel.h>
  267. # include    <mark.h>
  268. # include    <ports.h>
  269.  
  270. # ifdef    MEMMARK
  271. MARKER    ptmark;
  272. # endif
  273. struct ptnode    *ptfree;        /* list of free queue nodes          */
  274. struct pt    ports[NPORTS];
  275. int    ptnextp;
  276.  
  277. /*-----------------------------------------------------------------------------
  278.  *  pinit  --  initialize all ports
  279.  *-----------------------------------------------------------------------------
  280.  */
  281. SYSCALL    pinit(maxmsgs)
  282.     int    maxmsgs;
  283. {
  284.     int    i;
  285.     struct ptnode    *next, *prev;
  286.  
  287.     if ((ptfree=getmem(maxmsgs*sizeof(struct ptnode))) == SYSERR)
  288.         panic ("pinit - insufficient memory");
  289.     for (i=0 ; i<NPORTS ; i++)
  290.         ports[i].ptstate = PTFREE;
  291.     ptnextp = NPORTS - 1;
  292.  
  293.     /* link up free list of message pointer nodes */
  294.  
  295.     for (prev=next=ptfree ; --maxmsgs>0 ; prev=next)
  296.         prev->ptnext = ++next;
  297.     prev->ptnext = NULL;
  298.     return(OK);
  299. }
  300. /* poolinit.c - poolinit  p. 240 */
  301.  
  302. # include    <conf.h>
  303. # include    <kernel.h>
  304. # include    <mark.h>
  305. # include    <bufpool.h>
  306.  
  307. struct bpool    bptab[NBPOOLS];
  308. int    nbpools;
  309. # ifdef    MEMMARK
  310. MARKER    bpmark;                /* self initializing mark            */
  311. # endif
  312.  
  313. /*-----------------------------------------------------------------------------
  314.  *  poolinit  --  initialize the buffer pool routines
  315.  *-----------------------------------------------------------------------------
  316.  */
  317. poolinit()
  318. {
  319. # ifdef    MEMMARK
  320.     int    status;
  321.     char    ps;
  322.  
  323.     disable(ps);
  324.     if ((status=mark(bpmark)) == OK)  {
  325.         nbpools = 0;
  326.     }
  327.     restore(ps);
  328.     return((status==OK) ? OK : SYSERR);
  329. # else
  330.     nbpools = 0;
  331.     return(OK);
  332. # endif
  333. }
  334. /* preceive.c - preceive  p. 248 */
  335.  
  336. # include    <conf.h>
  337. # include    <kernel.h>
  338. # include    <mark.h>
  339. # include    <ports.h>
  340.  
  341. /*-----------------------------------------------------------------------------
  342.  *  preceive  --  receive a message from a port, blocking if port empty
  343.  *-----------------------------------------------------------------------------
  344.  */
  345. SYSCALL    preceive(portid)
  346.     int    portid;
  347. {
  348.     char    ps;
  349.     struct pt    *ptptr;
  350.     int    seq;
  351.     int    msg;
  352.     struct ptnode    *nxtnode;
  353.  
  354.     disable(ps);
  355.     if (isbadport(portid) ||
  356. # ifdef    MEMMARK
  357.         unmarked(ptmark) ||
  358. # endif
  359.         (ptptr=&ports[portid])->ptstate != PTALLOC)  {
  360.             restore(ps);
  361.             return(SYSERR);
  362.     }
  363.  
  364.     /* wait for message and verify that the port is still allocated */
  365.  
  366.     seq = ptptr->ptseq;
  367.     if (wait(ptptr->ptrsem) == SYSERR || ptptr->ptstate != PTALLOC
  368.        || ptptr->ptseq != seq)  {
  369.         restore(ps);
  370.         return(SYSERR);
  371.     }
  372.  
  373.     /* dequeue first message that is waiting in the port */
  374.  
  375.     nxtnode = ptptr->pthead;
  376.     msg = nxtnode->ptmsg;
  377.     if (ptptr->pthead == ptptr->pttail)    /* delete last item          */
  378.         ptptr->pthead = ptptr->pttail = NULL;
  379.     else
  380.         ptptr->pthead = nxtnode->ptnext;
  381.     nxtnode->ptnext = ptfree;        /* return to free list */
  382.     ptfree = nxtnode;
  383.     signal(ptptr->ptssem);
  384.     restore(ps);
  385.     return(msg);
  386. }
  387. /* psend.c - psend  p. 245 */
  388.  
  389. # include    <conf.h>
  390. # include    <kernel.h>
  391. # include    <mark.h>
  392. # include    <ports.h>
  393.  
  394. /*-----------------------------------------------------------------------------
  395.  *  psend  --  send a message to a port by enqueuing it
  396.  *-----------------------------------------------------------------------------
  397.  */
  398. SYSCALL    psend(portid, msg)
  399.     int    portid;
  400.     int    msg;
  401. {
  402.     char    ps;
  403.     struct pt    *ptptr;
  404.     int    seq;
  405.     struct ptnode    *freenode;
  406.  
  407.     disable(ps);
  408.     if (isbadport(portid) ||
  409. # ifdef    MEMMARK
  410.         unmarked(ptmark) ||
  411. # endif
  412.         (ptptr=&ports[portid])->ptstate != PTALLOC)  {
  413.             restore(ps);
  414.             return(SYSERR);
  415.     }
  416.  
  417.     /* wait for space and verify port is still allocated */
  418.  
  419.     seq = ptptr->ptseq;
  420.     if (wait(ptptr->ptssem) == SYSERR
  421.         || ptptr->ptstate != PTALLOC
  422.         || ptptr->ptseq != seq)  {
  423.             restore(ps);
  424.             return(SYSERR);
  425.     }
  426.     if (ptfree == NULL)
  427.         panic("Ports - out of nodes");
  428.     freenode = ptfree;
  429.     ptfree = freenode->ptnext;
  430.     freenode->ptnext = NULL;
  431.     freenode->ptmsg = msg;
  432.     if (ptptr->pttail == NULL)        /* empty queue               */
  433.         ptptr->pttail = ptptr->pthead = freenode;
  434.     else  {
  435.         (ptptr->pttail)->ptnext = freenode;
  436.         ptptr->pttail = freenode;
  437.     }
  438.     signal(ptptr->ptrsem);
  439.     restore(ps);
  440.     return(OK);
  441. }
  442. /* putc.c - putc  p. 147 */
  443.  
  444. # include    <conf.h>
  445. # include    <kernel.h>
  446. # include    <io.h>
  447.  
  448. /*-----------------------------------------------------------------------------
  449.  *  putc  --  write a single character to a device
  450.  *-----------------------------------------------------------------------------
  451.  */
  452. putc(descrp, ch)
  453.     int    descrp;
  454.     char    ch;
  455. {
  456.     struct devsw    *devptr;
  457.  
  458.     if (isbaddev(descrp))
  459.         return(SYSERR);
  460.     devptr = &devtab[descrp];
  461.     return ((*devptr->dvputc)(devptr,ch));
  462. }
  463.